package com.wh.wisdomsite.xbox.core.threadpool;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.wh.wisdomsite.xbox.core.util.NamedThreadFactory;

/**
 * 任务转发器
 * @Package com.wh.wisdomsite.xbox.core.threadpool
 * @author 谢泽鹏
 * @date 2014年10月8日 下午4:02:14
 * @Copyright 个人版权所有
 * @Company 贵州万华科技有限公司Copyright (c) 2014
 * @version V1.0
 */
public class JobDispathcher {

    private static final Log logger = LogFactory.getLog(JobDispathcher.class);

    //无Key的任务队列
    private static final String DEFAULT_JOBQUEUE = "JOB_DEFAULT_QUEUE";
    //消耗的线程数
    private static final String DEFAULT_COUNTER = "DEFAULT_COUNTER";
    //消耗的线程总数
    private static final String TOTAL_COUNTER = "TOTAL_COUNTER";
    //线程池核心值
    private static final String THREAD_POOL_CORE_SIZE = "THREAD_POOL_CORE_SIZE";
    //线程池最大值
    private static final String THREAD_POOL_MAX_SIZE = "THREAD_POOL_MAX_SIZE";
    //当前活动线程
    private static final String THREAD_POOL_ACTIVE_COUNT = "THREAD_POOL_ACTIVE_COUNT";
    //最大活动线程数
    private static final String THREAD_POOL_LARGEST_SIZE = "THREAD_POOL_LARGEST_SIZE";
    //已执行线程数
    private static final String THREAD_POOL_COMPLETED_COUNT = "THREAD_POOL_COMPLETED_COUNT";
    //权重模型
    private static final String THREAD_WEIGHT_MODEL = "THREAD_WEIGHT_MODEL";
    //当前线程池大小
    private static final String THREAD_POOL_CURRENT_SIZE = "THREAD_POOL_CURRENT_SIZE";
    //线程队列大小
    private static final String THREAD_POOL_QUEUE_SIZE = "THREAD_POOL_QUEUE_SIZE";
    //默认线程队列大小
    private static final String DEFAULT_QUEUE_COUNTER = "DEFAULT_QUEUE_COUNTER";
    //模型快照
    private static final String MODEL_SNAPSHOT = "MODEL_SNAPSHOT";



    /**
     * [线程池]核心线程数
     * 核心线程会一直存活，即使没有任务需要处理。
     * 当线程数小于核心线程数时，即使现有的线程空闲，线程池也会优先创建新线程来处理任务，而不是直接交给现有的线程处理。
     * 核心线程在allowCoreThreadTimeout被设置为true时会超时退出，默认情况下不会退出。
     *
     * 描述：
     * 每个任务需要tasktime秒处理，则每个线程每钞可处理1/tasktime个任务。
     * 系统每秒有tasks个任务需要处理，则需要的线程数为：tasks/(1/tasktime)，即tasks*tasktime个线程数。假设系统每秒任务数为100~1000，每个任务耗时0.1秒，
     * 则需要100*0.1至1000*0.1，即10~100个线程。那么corePoolSize应该设置为大于10，具体数字最好根据8020原则，即80%情况下系统每秒任务数，
     * 若系统80%的情况下第秒任务数小于200，最多时为1000，则corePoolSize可设置为20。
     *
     * [招商贷]corePoolSize分配：
     * 假设： 100 ~ 1000 , 则corePoolSize = 20
     *      1000 ~ 10000, 则corePoolSize = 200
     */
    private int corePoolSize = 200;


    /**
     * [线程池]最大线程数
     * 当线程数大于或等于核心线程，且任务队列已满时，线程池会创建新的线程，直到线程数量达到maxPoolSize。
     * 如果线程数已等于maxPoolSize，且任务队列已满，则已超出线程池的处理能力，线程池会拒绝处理任务而抛出异常。
     *
     * 描述：
     * 当系统负载达到最大值时，核心线程数已无法按时处理完所有任务，这时就需要增加线程。
     * 每秒200个任务需要20个线程，那么当每秒达到1000个任务时，则需要(1000-queueCapacity)*(20/200)，即60个线程，可将maxPoolSize设置为60。
     *
     * [招商贷]corePoolSize分配：
     * 假设： 100 ~ 1000 , 则maxPoolSize = 60
     *      1000 ~ 10000, 则corePoolSize = 600
     */
    private int maxPoolSize = 200;



    /**
     * 记录所有key所消耗的线程数.<br/>
     * key-预留模式,key所消耗的私有线程数量.counterPool最大数量为预留的最大值<br/>
     * key-限制模式,key所消耗的共有线程数量.<br/>
     */
    private Map<String, AtomicInteger> counterPool;

    /**
     * 记录所有key所消耗的实际线程数<br/>
     * <p>key-预留模式,key对应的所有线程数量.<br/>
     * 1：
     * 若配置先使用私有,若私有未使用完,则counterPool = defaultCounterPool,<br/>
     * 若使用完,则counterPool + (共有部分) = defaultcounter <br/>
     *
     * 2：
     * 若配置先使用共有,若共有未使用完,则counterPool = 0 ,defaultPoolCounter=实际使用线程数量<br/>
     * 若使用完,则counterPool +(共有部分) = defaultCounterPool<br/>
     * 总体来说:defaultCounterPool - counterPool = 使用的共有部分线程,<br/>
     * counterPool为私有的线程<br/></p>
     * <p>key-限制模式,key所消耗的共有线程数量 = counterPool中的数量<br/></p>
     */
    private Map<String, AtomicInteger> defaultCounterPool;



    /**
     * 所有key所对应的任务队列
     */
    private Map<String, JobQueue> jobQueuePool;


    /**
     * 线程的权重模型集合(预留模式/限制模式)
     */
    private JobThreadWeightModel[] jobThreadWeightModels;


    /**
     *
     */
    private JobThreadThreshold jobThreadThreshold;

    /**
     * 优先使用私有
     */
    private boolean privateUseFirst;

    /**
     * 消耗的线程总数
     */
    private AtomicInteger totalCounter;

    /**
     * 消耗的默认线程数.totalCounter - defaultCounter = 消耗的总私有线程
     * defaultCounter = 配置权重中消耗的线程+未配置key的权重线程.
     */
    private AtomicInteger defaultCounter;


    /**
     * 创建线程池对象
     */
    private JobThreadPoolExecutor jobThreadPoolExecutor;


    /**
     * 构造函数
     */
    public JobDispathcher() {

    }

    /**
     * 初始化
     */
    public void init() {
        logger.info("init->>线程容器开始启动...");
        //创建线程池
        if (null == jobThreadPoolExecutor) {
            jobThreadPoolExecutor = new JobThreadPoolExecutor(corePoolSize, maxPoolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>(), new NamedThreadFactory("jobDispatcher_worker"), this);
        }
        //初始化，默认消耗线程数
        this.defaultCounter = new AtomicInteger(0);
        //初始化，消耗线程总数
        this.totalCounter = new AtomicInteger(0);
        //初始化，实际消耗线程数集合
        this.defaultCounterPool = new ConcurrentHashMap<String, AtomicInteger>();
        //初始化，消耗线程池数集合
        this.counterPool = new ConcurrentHashMap<String, AtomicInteger>();
        //初始化，任务队列集合
        this.jobQueuePool = new ConcurrentHashMap<String, JobQueue>();
        //初始化，构建权重模式
        this.jobThreadThreshold = buildWeightModel(jobThreadWeightModels);
        //初始化，创建默认无key的任务队列
        JobQueue jobQueue = new JobQueue(DEFAULT_JOBQUEUE, maxPoolSize, this);
        //存放所有无key的任务队列
        jobQueuePool.put(DEFAULT_JOBQUEUE, jobQueue);
        logger.info("init->>线程容器启动成功....");
        logger.info("init->>线程状态...." + getCurrentThreadStatus());
    }

    /**
     * 重新构建线程权重模型
     * @param jobThreadWeightModels
     */
    public void rebuildWeightModel(JobThreadWeightModel[] jobThreadWeightModels) {
        this.jobThreadThreshold = buildWeightModel(jobThreadWeightModels);
    }


    /**
     * 线程权重模式
     * @param jobThreadWeightModels
     * @return
     */
    public JobThreadThreshold buildWeightModel(JobThreadWeightModel[] jobThreadWeightModels) {
        //this.jobThreadWeightModels = jobThreadWeightModels;
        //设置权重模式
        setJobThreadWeightModels(jobThreadWeightModels);
        //创建新的阀值控制对象,初始化完成后替换现有的.
        JobThreadThreshold newJobThreadThreshold = new JobThreadThreshold();
        newJobThreadThreshold.setDefaultThreshold(maxPoolSize);

        //1.若jobThreadWeightModels == null 则返回 jobThreadThreshold
        if (jobThreadWeightModels != null && jobThreadWeightModels.length > 0) {
            //遍历线程权重对象,设置对应的计数器和设置阀值对象
            for (JobThreadWeightModel job : jobThreadWeightModels) {
                //创建对应的线程队列 记录key对应的线程数量,若是重置线程,则已记录的线程数不能动
                if (!counterPool.containsKey(job.getKey())) {
                    counterPool.put(job.getKey(), new AtomicInteger(0));
                    defaultCounterPool.put(job.getKey(), new AtomicInteger(0));
                    JobQueue jobQueue = new JobQueue(job.getKey(), maxPoolSize, this);
                    jobQueuePool.put(job.getKey(), jobQueue);
                }
                //使用默认线程池
                if (job.getValue() == 0) {
                    continue;
                }
                //预留模式,设置预留,从总数中除去预留的
                if (JobThreadWeightModel.WEIGHT_MODEL_LEAVE.equals(job.getType())) {
                    newJobThreadThreshold.getThreadThreshold().put(job.getKey(), job.getValue());
                    newJobThreadThreshold.setDefaultThreshold(newJobThreadThreshold.getDefaultThreshold() - job.getValue());
                } else if (JobThreadWeightModel.WEIGHT_MODEL_LIMIT.equals(job.getType())) {
                    newJobThreadThreshold.getThreadThreshold().put(job.getKey(), job.getValue());
                } else {
                    throw new RuntimeException("model is not supported ! ");
                }
            }
            //检查配置
            if (newJobThreadThreshold.getDefaultThreshold() <= 0) {
                throw new RuntimeException("预留线程过多,超过最大可用线程数");
            }
            //遍历对象,设置阀值.
            for (JobThreadWeightModel job : jobThreadWeightModels) {
                if (job.getValue() == 0) {
                    continue;
                }
                //限制模式最大值小于等于未被占用的线程数,用负数表示limit模式,正数表示预留模式
                if (JobThreadWeightModel.WEIGHT_MODEL_LIMIT.equals(job.getType())) {
                    if (newJobThreadThreshold.getThreadThreshold().get(job.getKey()) > newJobThreadThreshold.getDefaultThreshold()) {
                        newJobThreadThreshold.getThreadThreshold().put(job.getKey(), -newJobThreadThreshold.getDefaultThreshold());
                    } else {
                        newJobThreadThreshold.getThreadThreshold().put(job.getKey(), -newJobThreadThreshold.getThreadThreshold().get(job.getKey()));
                    }
                }

            }
        }
        return newJobThreadThreshold;
    }


    /**
     * 获取当前线程状态
     * @return
     */
    public Map<String, Object> getCurrentThreadStatus() {
        Map<String, Object> status = new HashMap<String, Object>();
        //线程池核心值THREAD_POOL_CORE_SIZE
        status.put(THREAD_POOL_CORE_SIZE, jobThreadPoolExecutor.getCorePoolSize());
        //线程池最大值THREAD_POOL_MAX_SIZE
        status.put(THREAD_POOL_MAX_SIZE, jobThreadPoolExecutor.getMaximumPoolSize());
        //当前活动线程THREAD_POOL_ACTIVE_COUNT
        status.put(THREAD_POOL_ACTIVE_COUNT, jobThreadPoolExecutor.getActiveCount());
        //已执行线程THREAD_POOL_COMPLETED_COUNT
        status.put(THREAD_POOL_COMPLETED_COUNT, jobThreadPoolExecutor.getCompletedTaskCount());
        //最大活动数THREAD_POOL_LARGEST_SIZE
        status.put(THREAD_POOL_LARGEST_SIZE, jobThreadPoolExecutor.getLargestPoolSize());
        //当前线程池大小THREAD_POOL_CURRENT_SIZE
        status.put(THREAD_POOL_CURRENT_SIZE, jobThreadPoolExecutor.getPoolSize());
        //队列个数THREAD_POOL_QUEUE_SIZE
        status.put(THREAD_POOL_QUEUE_SIZE, jobThreadPoolExecutor.getQueue().size());
        //消耗的默认线程数DEFAULT_COU
        status.put(DEFAULT_COUNTER, defaultCounter.get());
        //消耗的线程总数TOTAL_COUNTER
        status.put(TOTAL_COUNTER, totalCounter.get());
        //默认线程队列大小DEFAULT_QUEUE_COUNTER
        status.put(DEFAULT_QUEUE_COUNTER, jobQueuePool.get(DEFAULT_JOBQUEUE).size());

        //权重模型
        StringBuffer sb = new StringBuffer();
        if (jobThreadWeightModels != null) {
            for (JobThreadWeightModel model : jobThreadWeightModels) {
                sb.append(model.getType()).append(":").append(model.getKey()).append(":").append(model.getValue()).append(",");
            }
        }
        if (sb.length() > 0) {
            //权重模型THREAD_WEIGHT_MODEL
            status.put(THREAD_WEIGHT_MODEL, sb.substring(0, sb.length() - 1));
        }

        //模型快照
        StringBuilder detailModelStatus = new StringBuilder();
        Iterator<Map.Entry<String, AtomicInteger>> entrys = counterPool.entrySet().iterator();
        while (entrys.hasNext()) {
            Map.Entry<String, AtomicInteger> e = entrys.next();
            detailModelStatus.append(e.getKey()).append("=").append(
                    new StringBuilder("private:").append(e.getValue())
                            .append(",total:").append(defaultCounterPool.get(e.getKey()).get())
                            .append(",queue:").append(jobQueuePool.get(e.getKey()).size()).toString()).append(";");

        }
        if (detailModelStatus.length() > 0) {
            //模型快照MODEL_SNAPSHOT
            status.put(MODEL_SNAPSHOT, detailModelStatus.substring(0, detailModelStatus.length() - 1));
        }
        return status;
    }


    /**
     * 获取当前线程信息
     * @return
     */
    public Map<String, Object> getCurrentThreadMessage() {
        Map<String, Object> status = new HashMap<String, Object>();
        //线程池核心值THREAD_POOL_CORE_SIZE
        status.put("线程池核心值", jobThreadPoolExecutor.getCorePoolSize());
        //线程池最大值THREAD_POOL_MAX_SIZE
        status.put("线程池最大值", jobThreadPoolExecutor.getMaximumPoolSize());
        //当前活动线程THREAD_POOL_ACTIVE_COUNT
        status.put("当前活动线程", jobThreadPoolExecutor.getActiveCount());
        //已执行线程THREAD_POOL_COMPLETED_COUNT
        status.put("已执行线程", jobThreadPoolExecutor.getCompletedTaskCount());
        //最大活动数THREAD_POOL_LARGEST_SIZE
        status.put("最大活动数", jobThreadPoolExecutor.getLargestPoolSize());
        //当前线程池大小THREAD_POOL_CURRENT_SIZE
        status.put("当前线程池大小", jobThreadPoolExecutor.getPoolSize());
        //队列个数THREAD_POOL_QUEUE_SIZE
        status.put("队列个数", jobThreadPoolExecutor.getQueue().size());
        //消耗的默认线程数DEFAULT_COUNTER
        status.put("消耗的默认线程数", defaultCounter.get());
        //消耗的线程总数TOTAL_COUNTER
        status.put("消耗的线程总数", totalCounter.get());
        //默认线程队列大小DEFAULT_QUEUE_COUNTER
        status.put("默认线程队列大小", jobQueuePool.get(DEFAULT_JOBQUEUE).size());

        //权重模型
        StringBuffer sb = new StringBuffer();
        if (jobThreadWeightModels != null) {
            for (JobThreadWeightModel model : jobThreadWeightModels) {
                sb.append(model.getType()).append(":").append(model.getKey()).append(":").append(model.getValue()).append(",");
            }
        }
        if (sb.length() > 0) {
            //权重模型THREAD_WEIGHT_MODEL
            status.put("权重模型", sb.substring(0, sb.length() - 1));
        }

        //模型快照
        StringBuilder detailModelStatus = new StringBuilder();
        Iterator<Map.Entry<String, AtomicInteger>> entrys = counterPool.entrySet().iterator();
        while (entrys.hasNext()) {
            Map.Entry<String, AtomicInteger> e = entrys.next();
            detailModelStatus.append(e.getKey()).append("=").append(new StringBuilder("private:").append(e.getValue()).append(",total:").append(defaultCounterPool.get(e.getKey()).get()).append(",queue:").append(jobQueuePool.get(e.getKey()).size()).toString()).append(";");
        }
        if (detailModelStatus.length() > 0) {
            //模型快照MODEL_SNAPSHOT
            status.put("模型快照", detailModelStatus.substring(0, detailModelStatus.length() - 1));
        }
        return status;
    }


    /**
     * 关闭线程池容器
     * 1,若JobQueue中还有未完成任务,则等待队列任务完成
     * 2,等待正在执行的任务完成.
     */
    public void stopDispatcher() {
        logger.info("stopDispatcher->>开始关闭线程池容器....");
        //获取jobQueuePool线程队列任务大小
        if (jobQueuePool != null && jobQueuePool.size() > 0) {
            //循环判断jobQueuePool(线程队列任务)中JobQueue(任务)是否存在未完成任务。若存在，则等待所有任务完成,在清理。
            //是否完成
            boolean isCompleted = false;
            while (!isCompleted) {
                boolean flag = true;
                for (String key : jobQueuePool.keySet()) {
                    JobQueue jobQueue = jobQueuePool.get(key);
                    flag = flag & jobQueue.isCompleted();
                }
                try {
                    //存在未完成的任务
                    if (!flag) {
                        Thread.sleep(5000);
                    } else {
                        isCompleted = true;
                    }
                } catch (InterruptedException e) {
                    //do nothing
                }
                logger.info("stopDispatcher->>关闭线程池容器->>线程池中存在未完成的任务队列，继续等待！！！");
            }

            for (String key : jobQueuePool.keySet()) {
                JobQueue jobQueue = jobQueuePool.get(key);
                jobQueue.clean();
            }
            jobQueuePool.clear();
            logger.info("stopDispatcher->>关闭线程池容器->>集合中清除所有任务队列");
        }

        if (jobThreadPoolExecutor != null) {
            jobThreadPoolExecutor.shutdown();
        }
        //主线程池关闭后,再清理
        if (null != jobThreadPoolExecutor && jobThreadPoolExecutor.isTerminated()) {
            if (null != jobThreadThreshold.getThreadThreshold()) {
                jobThreadThreshold.getThreadThreshold().clear();
            }
            if (null != counterPool) {
                counterPool.clear();
            }
            if (null != defaultCounterPool) {
                defaultCounterPool.clear();
            }
            logger.info("stopDispatcher->>关闭线程池容器->>资源清理");
        }
            logger.info("stopDispatcher->>关闭线程池容器->>线程池容器关闭成功！！！");
    }


    /**
     * 检查资源
     * @param job
     * @return
     */
    public boolean checkResource(Job job) {
        //默认无资源
        boolean hasResource = false;
        //判断总量
        if (totalCounter.incrementAndGet() > maxPoolSize) {
            totalCounter.decrementAndGet();
            return false;
        }
        //获取key
        String key = job.getKey();
        //预留模式
        Integer threshold = null;
        if (key != null) {
            threshold = this.jobThreadThreshold.getThreadThreshold().get(key);
        }


        //key == null 创建的job未分配key值 ,使用默认线程
        //threshold == null 新的key在权重模型找不到或更新了权重模型找不到该key 总体:在权重模型找不到.
        //从默认资源中获取

        //判断(若key == null 创建的job(任务)为分配key值, 使用默认线程)
        if (key == null || threshold == null) {
            if (defaultCounter.incrementAndGet() > this.jobThreadThreshold.getDefaultThreshold()) {
                defaultCounter.decrementAndGet();
            } else {
                hasResource = true;
            }
        }

        //
        else {
            AtomicInteger counter = counterPool.get(key);
            //预留模式
            if (threshold > 0) {
                //私有优先
                if (privateUseFirst) {
                    //判断私有的 私有是否用完,若用完,则使用共有
                    if (counter.incrementAndGet() > threshold) {
                        counter.decrementAndGet();
                        //使用共有前,先检查阀值
                        if (defaultCounter.incrementAndGet() > jobThreadThreshold.getDefaultThreshold()) {
                            defaultCounter.decrementAndGet();
                        } else {
                            hasResource = true;
                        }
                    } else {
                        hasResource = true;
                    }
                } else {
                    //先使用共有资源,共有使用完,则使用私有的,检查阀值
                    if (defaultCounter.incrementAndGet() > jobThreadThreshold.getDefaultThreshold()) {
                        defaultCounter.decrementAndGet();
                        if (counter.incrementAndGet() > threshold) {
                            counter.decrementAndGet();
                        } else {
                            hasResource = true;
                        }
                    } else {
                        hasResource = true;
                    }
                }
            } else {//限制模式 //首先检查阀值
                if (counter.incrementAndGet() > -threshold) {
                    counter.decrementAndGet();
                } else {
                    if (defaultCounter.incrementAndGet() > jobThreadThreshold.getDefaultThreshold()) {
                        defaultCounter.decrementAndGet();
                        counter.decrementAndGet();
                    } else {
                        hasResource = true;
                    }
                }
            }
        }

        if (!hasResource) {
            totalCounter.decrementAndGet();
        }
        return hasResource;
    }

    /**
     * 执行器,当任务饱和时抛出 {@link java.util.concurrent.RejectedExecutionException}
     * @param job
     */
    public void execute(Job job) {
        boolean hasResource = checkResource(job);
        if (hasResource) {
            inncExecute(job);
        } else {
            pushJob(job);
        }
    }


    /**
     * 执行任务
     * @param job
     */
    public void inncExecute(Job job) {
        jobThreadPoolExecutor.execute(job);
    }


    /**
     * 任务队列存放任务
     * @param job
     */
    public void pushJob(Job job) {
        JobQueue jobQueue = getJobQueue(job);
        if (!jobQueue.offer(job)) {
            logger.error("pushJob->>任务队列已满，无法添加新的任务.." + job.getKey() + "-" + Thread.currentThread() + getCurrentThreadStatus());
            throw new RejectedExecutionException("任务队列已满，无法添加新的任务.." + job.getKey() + "-" + Thread.currentThread() + getCurrentThreadStatus());
        }
    }


    /**
     * 获取任务队列
     * @param job
     * @return
     */
    public JobQueue getJobQueue(Job job) {
        JobQueue jobQueue = null;
        if (null == job || job.getKey() == null || !counterPool.containsKey(job.getKey())) {
            //无key的任务队列
            jobQueue = jobQueuePool.get(DEFAULT_JOBQUEUE);
        } else {
            //有key的任务队列
            jobQueue = jobQueuePool.get(job.getKey());
        }
            return jobQueue;
    }

    /**
     * 执行前,将已设置权重的job放入defaultCounterPool中.
     * @param job
     */
    public void beforeExecute(Job job) {
        if (job.getKey() != null && defaultCounterPool.containsKey(job.getKey())) {
            defaultCounterPool.get(job.getKey()).incrementAndGet();
        }
    }

    /**
     * 释放资源
     * @param job
     */
    public void releaseResource(Job job) {
        String key = null;
        if(null != job){
            key = job.getKey();
        }

        totalCounter.decrementAndGet();

        //没有权重线程被记录(counterPool == 0 权重对象为空) key == null 则key使用默认线程数
        if (counterPool.size() == 0 || key == null) {
            defaultCounter.decrementAndGet();
        } else {
            AtomicInteger counter = counterPool.get(key);
            //keyd对应的value 为0 ,初始化或重定义key权重修改的值
            if (counter != null) {
                //1,从defaultcounterPool中key对应的所有线程中扣除
                if (defaultCounterPool.get(key) != null) {
                    defaultCounterPool.get(key).decrementAndGet();
                }

                //2,从key对应counterpool中扣除,注意预留和限制模式
//                Integer size = jobThreadThreshold.getThreadThreshold().get(key);
//                if (size == null || size < 0) {//限制
//                    defaultCounter.decrementAndGet();
//                    if(counter.decrementAndGet() < 0){
//                        counter.incrementAndGet();
//                    }
//                    //counter.decrementAndGet();
//                } else {//预留 defaultcounterPool - counterPool = 耗用共有资源
//                    if (counter.decrementAndGet() < 0) {//私有线程已全部归还,说明耗用的默认线程.
//                        counter.incrementAndGet();
//                        defaultCounter.decrementAndGet();
//                    }
//                }

                /*
                 //2,从key对应counterpool中扣除,注意预留和限制模式
                //leave,limit,对于counter来说总是需要先扣除. 如果是leave,则先扣除私有部分,
                // 如果是limit,则扣除counter部分
                //扣除后,小于0,说明counter已经扣完,则增加回来,扣除默认.
                //从key对应的counter中扣除. 1(预留模式)defaultcounter = counterPool + 共有部分
                // 2(限制模式) defaultcounter = counterPool
                */
                if (counter.decrementAndGet() < 0) { //leave mode
                    counter.incrementAndGet();
                    defaultCounter.decrementAndGet();
                } else {
                    //counter扣除后不为0 则判断模式 key->leave key->limit TODO 可能存在重复扣除 defaultCounter
                    Integer size = jobThreadThreshold.getThreadThreshold().get(key);
                    //size == null 新key
                    //size < 0 limit模式
                    if ((null == size) || (null != size && size < 0)) {// limit mode (use default)
                        defaultCounter.decrementAndGet();
                    }

//                    else {// leave mode (use itself) //counter.decrementAndGet() >0 说明预留模式中的线程尚未消耗完毕.
//                        //nothing
//                    }
                }

            } else {//key == null 为新值不存在counter中.counter只有在权重初始化时赋值
                defaultCounter.decrementAndGet();
            }
        }
        JobQueue jobQueue = getJobQueue(job);
        jobQueue.notifyHasResource();
    }

    public boolean isPrivateUseFirst() {
        return privateUseFirst;
    }

    public void setPrivateUseFirst(boolean privateUseFirst) {
        this.privateUseFirst = privateUseFirst;
    }

    public int getMaxPoolSize() {
        return maxPoolSize;
    }

    public void setMaxPoolSize(int maxPoolSize) {
        this.maxPoolSize = maxPoolSize;
    }

    public Map<String, AtomicInteger> getCounterPool() {
        return counterPool;
    }

    public void setCounterPool(Map<String, AtomicInteger> counterPool) {
        this.counterPool = counterPool;
    }

    public Map<String, AtomicInteger> getDefaultCounterPool() {
        return defaultCounterPool;
    }

    public void setDefaultCounterPool(Map<String, AtomicInteger> defaultCounterPool) {
        this.defaultCounterPool = defaultCounterPool;
    }

    public Map<String, JobQueue> getJobQueuePool() {
        return jobQueuePool;
    }

    public void setJobQueuePool(Map<String, JobQueue> jobQueuePool) {
        this.jobQueuePool = jobQueuePool;
    }

    public JobThreadWeightModel[] getJobThreadWeightModels() {
        return jobThreadWeightModels;
    }

    public void setJobThreadWeightModels(JobThreadWeightModel[] jobThreadWeightModels) {
        this.jobThreadWeightModels = jobThreadWeightModels;
    }

    public JobThreadThreshold getJobThreadThreshold() {
        return jobThreadThreshold;
    }

    public void setJobThreadThreshold(JobThreadThreshold jobThreadThreshold) {
        this.jobThreadThreshold = jobThreadThreshold;
    }

    public int getCorePoolSize() {
        return corePoolSize;
    }

    public void setCorePoolSize(int corePoolSize) {
        this.corePoolSize = corePoolSize;
    }

    public JobThreadPoolExecutor getJobThreadPoolExecutor() {
        return jobThreadPoolExecutor;
    }

    public void setJobThreadPoolExecutor(JobThreadPoolExecutor jobThreadPoolExecutor) {
        this.jobThreadPoolExecutor = jobThreadPoolExecutor;
    }
}
